package com.ibeeking.found.upms.b.rest.service.impl;

import com.ibeeking.found.common.entity.CurrentUser;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.upms.b.rest.service.ITenantRoleService;
import com.ibeeking.found.upms.b.rest.service.ITenantUserRoleService;
import com.ibeeking.found.upms.b.rest.service.ITenantUserService;
import com.ibeeking.found.upms.service.common.bo.TenantUserBO;
import com.ibeeking.found.upms.service.common.bo.TenantUserRoleBO;
import com.ibeeking.found.upms.service.common.bo.TenantUserRoleInfoBO;
import com.ibeeking.found.upms.service.common.dos.TenantUserRoleDO;
import com.ibeeking.found.upms.service.common.param.RoleUserParam;
import com.ibeeking.found.upms.service.common.param.UserRoleParam;
import com.ibeeking.found.upms.service.common.po.TenantUserRolePO;
import com.ibeeking.found.upms.service.mapper.TenantUserRoleMapper;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.json.JsonUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @project: found-upms
 * @description: 用户角色关系实现类
 * @Author ibeeking
 * @create: 2020-12-05 13:30:46
 **/
@Service
public class TenantUserRoleServiceImpl extends ServiceImpl<TenantUserRoleMapper, TenantUserRoleDO> implements ITenantUserRoleService {

    @Resource
    private TenantUserRoleMapper tenantUserRoleMapper;
    @Resource
    private ITenantUserService userServiceImpl;
    @Resource
    private ITenantRoleService roleServiceImpl;

    @Override
    public List<TenantUserRoleBO> queryUserRoleByUserId(Long userId) {
        List<TenantUserRoleDO> tenantUserRoleDOS = tenantUserRoleMapper.selectList(new LambdaQueryWrapper<>(TenantUserRoleDO.class).eq(TenantUserRoleDO::getUserId, userId));
        if (Collections3.isEmpty(tenantUserRoleDOS)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(tenantUserRoleDOS, TenantUserRoleBO.class);
    }

    @Override
    public List<TenantUserRoleBO> queryUserRoleByRoleId(Long roleId) {
        List<TenantUserRoleDO> userRoleDoS = tenantUserRoleMapper.selectList(new LambdaQueryWrapper<>(TenantUserRoleDO.class).eq(TenantUserRoleDO::getRoleId, roleId));
        if (Collections3.isEmpty(userRoleDoS)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(userRoleDoS, TenantUserRoleBO.class);
    }

    @Transactional(rollbackFor = {BusinessException.class})
    @Override
    public Boolean modifyUserRoleByUserId(CurrentUser currentUser, UserRoleParam userRoleParam) {
        if (currentUser.getId().equals(userRoleParam.getUserId())) {
            throw new BusinessException("禁止修改自己的角色");
        }
        TenantUserBO tenantUserBO = userServiceImpl.queryById(userRoleParam.getUserId());
        if (PublishStatusEnum.DISABLE.getValue().equals(tenantUserBO.getPublishStatus()) || PublishStatusEnum.DISABLE.getValue().equals(tenantUserBO.getJob())) {
            throw new BusinessException("用户已离职或被锁定，禁止配置角色");
        }
        Long administratorId = roleServiceImpl.selectAdministratorId();
        //查询超级管理员对应的用户id
        List<TenantUserRoleBO> tenantUserRoleBos1 = queryUserRoleByRoleIds(Arrays.asList(administratorId));
        tenantUserRoleMapper.delete(new LambdaQueryWrapper<>(TenantUserRoleDO.class)
                .eq(TenantUserRoleDO::getUserId, userRoleParam.getUserId()));

        // 1. 查询现有用户角色id列表
        List<TenantUserRoleBO> tenantUserRoleBos = queryUserRoleByUserId(currentUser.getId());
        List<Long> haveRoleIds = tenantUserRoleBos.parallelStream().map(TenantUserRoleBO::getRoleId).collect(Collectors.toList());
        if (null == userRoleParam.getRoleIds() || 0 == userRoleParam.getRoleIds().length) {
            if (haveRoleIds.contains(administratorId)) {
                throw new BusinessException("超级管理员至少要有1个用户");
            }
            return true;
        }
        List<Long> paramIds = Arrays.asList(userRoleParam.getRoleIds());
        if (paramIds.contains(administratorId)) {
            if (Collections3.isEmpty(tenantUserRoleBos1)) {
                throw new BusinessException("非超级管理员禁止配置超级管理员角色");
            } else {
                Long userId = tenantUserRoleBos1.get(0).getUserId();
                if (userRoleParam.getUserId().equals(userId) && !currentUser.getId().equals(userId)) {
                    throw new BusinessException("非超级管理员禁止配置超级管理员角色");
                }
                //删除超级管理员关联用户
                tenantUserRoleMapper.delete(new LambdaQueryWrapper<>(TenantUserRoleDO.class)
                        .eq(TenantUserRoleDO::getRoleId, administratorId));
                paramIds = new ArrayList<>();
                paramIds.add(administratorId);
            }
        } else {
            if (!Collections3.isEmpty(tenantUserRoleBos1)) {
                Long userId = tenantUserRoleBos1.get(0).getUserId();
                if (userRoleParam.getUserId().equals(userId) && !currentUser.getId().equals(userId)) {
                    throw new BusinessException("非超级管理员禁止配置超级管理员角色");
                }
            }
        }
        //新增关系
        List<TenantUserRoleDO> saves = new ArrayList<>();
        paramIds.stream().forEach(key -> {
            TenantUserRoleDO userRoleDO = new TenantUserRoleDO();
            userRoleDO.setRoleId(key);
            userRoleDO.setUserId(userRoleParam.getUserId());
            saves.add(userRoleDO);
        });
        // 新增关系
        tenantUserRoleMapper.insertBatchSomeColumn(saves);
        return true;
    }

    @Transactional(rollbackFor = {BusinessException.class})
    @Override
    public Boolean modifyUserRoleByRoleId(CurrentUser currentUser, RoleUserParam roleUserParam) {
        Long administratorId = roleServiceImpl.selectAdministratorId();
        //查询超级管理员对应的用户id
        List<TenantUserRoleBO> tenantUserRoleBos1 = queryUserRoleByRoleIds(Arrays.asList(administratorId));
        tenantUserRoleMapper.delete(new LambdaQueryWrapper<>(TenantUserRoleDO.class)
                .eq(TenantUserRoleDO::getRoleId, roleUserParam.getRoleId()));

        if (null == roleUserParam.getUserIds() || 0 == roleUserParam.getUserIds().length) {
            if (roleUserParam.getRoleId().equals(administratorId)) {
                throw new BusinessException("超级管理员至少选择一个用户");
            }
            return true;
        }
        List<Long> paramIds = Arrays.asList(roleUserParam.getUserIds());
        if (roleUserParam.getRoleId().equals(administratorId)) {
            if (paramIds.size() > 1) {
                throw new BusinessException("超级管理员至多选择一个用户");
            }
            if (Collections3.isEmpty(tenantUserRoleBos1)) {
                throw new BusinessException("非超级管理员禁止配置超级管理员角色");
            } else {
                Long userId = tenantUserRoleBos1.get(0).getUserId();
                if (paramIds.contains(userId) && !currentUser.getId().equals(userId)) {
                    throw new BusinessException("非超级管理员禁止配置超级管理员角色");
                }
            }
        }
        //新增关系
        List<TenantUserRoleDO> saves = new ArrayList<>();
        paramIds.parallelStream().forEach(key -> {
            TenantUserRoleDO userRoleDO = new TenantUserRoleDO();
            userRoleDO.setRoleId(roleUserParam.getRoleId());
            userRoleDO.setUserId(key);
            saves.add(userRoleDO);
        });
        tenantUserRoleMapper.insertBatchSomeColumn(saves);
        return true;
    }

    @Override
    public List<TenantUserRoleInfoBO> queryUserRoleByUserIds(List<Long> userIds) {
        if (Collections3.isEmpty(userIds)) {
            return Collections3.emptyList();
        }
        List<TenantUserRolePO> list = tenantUserRoleMapper.queryUserRoleByUserIds(userIds);
        if (Collections3.isEmpty(list)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(list, TenantUserRoleInfoBO.class);
    }

    @Override
    public List<TenantUserRoleBO> queryUserRoleByRoleIds(List<Long> roleIds) {
        List<TenantUserRoleDO> tenantUserRoleDOS = tenantUserRoleMapper.selectList(new LambdaQueryWrapper<>(TenantUserRoleDO.class).in(TenantUserRoleDO::getRoleId, roleIds));
        if (Collections3.isEmpty(tenantUserRoleDOS)) {
            return Collections3.emptyList();
        }
        return JsonUtils.jsonToList(tenantUserRoleDOS, TenantUserRoleBO.class);
    }
}
